package com.example.response.config;

import com.example.response.annotation.ExceptionCodeAnnotation;
import com.example.response.enums.ResultCodeEnum;
import com.example.response.exception.ApiException;
import com.example.response.vo.ResultVO;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.lang.reflect.Field;

/**
 * 全局异常类
 */
@RestControllerAdvice
public class ExceptionControllerAdvice {

    //指定异常类型捕捉，未统一响应体
//    @ExceptionHandler(BindException.class)
//    public String bindExceptionHandler(BindException exception){
//        ObjectError objectError = exception.getBindingResult().getAllErrors().get(0);
//        return objectError.getDefaultMessage();
//    }
    //指定异常类型捕捉，统一响应体，未规范响应码
//    @ExceptionHandler(BindException.class)
//    public ResultVO<String> bindExceptionHandler(BindException exception){
//        ObjectError objectError = exception.getBindingResult().getAllErrors().get(0);
//        return new ResultVO<>(1000, "参数错误", objectError.getDefaultMessage());
//    }
    //指定异常类型捕捉，统一响应体，规范响应码，不能根据字段灵活返回code和msg。
//    @ExceptionHandler(BindException.class)
//    public ResultVO<String> bindExceptionHandler(BindException exception){
//        ObjectError objectError = exception.getBindingResult().getAllErrors().get(0);
//        return new ResultVO<>(ResultCodeEnum.VALIDATE_FAILED, objectError.getDefaultMessage());
//    }
    //指定异常类型捕捉，统一响应体，规范响应码，并根据自定义注解返回我们定制的code和msg。
    @ExceptionHandler(BindException.class)
    public ResultVO<String> bindExceptionHandler(BindException exception) throws NoSuchFieldException {
        // 从异常对象中获取错误信息
        String errorMsg = exception.getBindingResult().getAllErrors().get(0).getDefaultMessage();
        //获取异常的类对象
        Class<?> aClass = exception.getBindingResult().getTarget().getClass();
        //获取属性名：nickName
        String field = exception.getBindingResult().getFieldError().getField();
//        String fieldName = exception.getBindingResult().getFieldError().getObjectName();//获取对象名: user
        //获取被声明属性所有信息：得到一个属性对象Field
        Field declaredField = aClass.getDeclaredField(field);
//        //获取该属性对应的自定义注解
        ExceptionCodeAnnotation exceptionCodeAnnotation = declaredField.getAnnotation(ExceptionCodeAnnotation.class);
        Class<? extends BindingResult> aClass1 = exception.getBindingResult().getClass();
        if(exceptionCodeAnnotation != null){
            return new ResultVO<>(exceptionCodeAnnotation.code(),exceptionCodeAnnotation.message(),errorMsg);
        }
        return new ResultVO<>(ResultCodeEnum.VALIDATE_FAILED, errorMsg);
    }

    //自定义异常类型捕捉，未统一响应体
//    @ExceptionHandler(ApiException.class)
//    public String apiExceptionHandler(ApiException apiException){
//        return apiException.getMessage();
//    }
    //自定义异常类型捕捉，统一响应体，未规范响应码
//    @ExceptionHandler(ApiException.class)
//    public ResultVO<String> apiExceptionHandler(ApiException apiException){
//        return new ResultVO<>(apiException.getCode(),"接口异常", apiException.getMsg());
//    }
    //自定义异常类型捕捉，统一响应体，规范响应码，不能根据字段灵活返回code和msg。运行时异常不需要很复杂的code和msg，ResultCodeEnum可以满足
    @ExceptionHandler(ApiException.class)
    public ResultVO<String> apiExceptionHandler(ApiException apiException){
        return new ResultVO<>(ResultCodeEnum.FAILED, apiException.getMsg());
    }


}
